package com.mygame.components

import com.almasb.fxgl.dsl.FXGL
import com.almasb.fxgl.dsl.getGameWorld
import com.almasb.fxgl.entity.Entity
import com.almasb.fxgl.entity.SpawnData
import com.almasb.fxgl.entity.component.Component
import com.mygame.Const
import com.mygame.Dir
import com.mygame.EType
import com.mygame.spawn
import com.mygame.weapons.MachineGun
import javafx.geometry.Point2D
import javafx.scene.input.KeyCode
import javafx.scene.paint.Color

class ControllerComponent : Component() {
    private var comboComponent: ComboComponent? = null
    private lateinit var jumpPoint: Point2D
    private var isJumping = false
    private var jumpSpeed = -500.0
    private val gravity = 1000.0
    private var jumpCount = 0
    private val MAX_JUMP_COUNT = 1


    private val SPEED = 100.0 // 移动速度，单位：像素/秒
    private var shootDir = Dir.RIGHT
    private var tpf = 0.0
    val machineGun = MachineGun()
    private var barrelEntity: Entity? = null
    private lateinit var walls: List<Entity>
    override fun onAdded() {
        super.onAdded()
        comboComponent = entity.getComponent(ComboComponent::class.java)
        if (entity.properties.exists(Const.WIDGET_ENTITY)){
            barrelEntity = entity.properties.getObject<Entity>(Const.WIDGET_ENTITY)
        }
        walls = getGameWorld().getEntitiesByType(EType.WALL)
    }

    fun up() {
        move(Dir.UP, -90.0, -SPEED * tpf, true)
        comboComponent?.addInputKeys(KeyCode.UP.name)
    }

    fun down() {
        move(Dir.DOWN, 90.0, SPEED * tpf, true)
        comboComponent?.addInputKeys(KeyCode.DOWN.name)
    }

    fun left() {
        move(Dir.LEFT, -180.0, -SPEED * tpf, false)
        comboComponent?.addInputKeys(KeyCode.LEFT.name)
    }

    fun right() {
        move(Dir.RIGHT, 0.0, SPEED * tpf, false)
        comboComponent?.addInputKeys(KeyCode.RIGHT.name)
    }

    fun move(dir: Dir, angle: Double, moveSpeed: Double, isYDir: Boolean = true) {
        shootDir = dir
        entity.rotation = angle

        var isCanMove = true
        for (wall in walls) {
            when (dir) {
                Dir.UP -> {
                    if (wall.center.y + wall.height / 2 < entity.center.y - entity.height / 2
                        && entity.distanceBBox(wall) < 2
                    ) {
                        isCanMove = false
                        //println("↑撞墙了 e:${entity.center.y - entity.height / 2} w:${wall.center.y + wall.height / 2}")
                        break
                    }
                }

                Dir.DOWN -> {
                    if (wall.center.y - wall.height / 2 > entity.center.y + entity.height / 2
                        && entity.distanceBBox(wall) < 2
                    ) {
                        isCanMove = false
                        //println("↓撞墙了 e:${entity.center.y + entity.height / 2} w:${wall.center.y - wall.height / 2}")
                        break
                    }
                }

                Dir.LEFT -> {
                    if ((wall.center.x + wall.width / 2) < (entity.center.x - entity.width / 2)
                        && entity.distanceBBox(wall) < 2
                    ) {
                        //println("←撞墙了 e:${entity.center.x - entity.width / 2} w:${wall.center.x + wall.width / 2}")
                        isCanMove = false
                        break
                    }
                }

                Dir.RIGHT -> {
                    if (wall.center.x - wall.width / 2 > entity.center.x + entity.width / 2
                        && entity.distanceBBox(wall) < 2
                    ) {
                        //println("→撞墙了 e:${entity.center.x + entity.width / 2} w:${wall.center.x - wall.width / 2}")
                        isCanMove = false
                        break
                    }
                }
            }
            isCanMove = true
        }
        if (isCanMove) {
            if (isYDir) {
                entity.translateY(moveSpeed)
                //barrelEntity.translateY(moveSpeed)
            } else {
                entity.translateX(moveSpeed)
                //barrelEntity.translateX(moveSpeed)
            }
        }
    }

    fun jump() {
        if (!isJumping && jumpCount < MAX_JUMP_COUNT) {
            jumpPoint = entity.position
            // 如果角色没有在跳跃中，并且跳跃次数没有超过最大值，开始跳跃
            isJumping = true
            jumpSpeed = -500.0
            jumpCount++
        }
    }

    private fun updateJumping() {
        if (isJumping) {
            // 在跳跃过程中，每一帧都更新角色的位置
            val y = entity.position.y
            val newY = y + jumpSpeed * tpf
            entity.setPosition(entity.position.x, newY)
            jumpSpeed += gravity * tpf
            //println("jumpSpeed=$jumpSpeed  newY=$newY  entity.position.y=${entity.position.y}")
            // 如果角色已经落地，停止跳跃
            if (jumpSpeed >= 500.0) {
                isJumping = false
                jumpCount = 0
                entity.setPosition(entity.position.x, jumpPoint.y)
            }
        }
    }

    fun getShootDir(): Dir {
        return shootDir
    }

    //射击子弹
    fun shoot(isLongShoot: Boolean = false, vararg vector: Point2D) {
        var dir = if (vector.isNotEmpty()) {
            vector[0]
        } else {
            barrelEntity?.rotation = entity.rotation
            shootDir.value
        }
        var r = machineGun.size / 2
        if (isLongShoot) {
            r *= 2
        }
        //println("size=$r")
        spawn(
            EType.BULLET,
            SpawnData(entity.center.x - r, entity.center.y - r)
                .put(Const.RADIUS, r)
                .put(Const.DIR, dir)
                .put(Const.SPEED, machineGun.shootSpeed)
                .put(Const.COLOR, Color.BLACK)
        )
    }

    fun clickShoot(vararg isLongShoot: Boolean) {
        //点击坐标点
        val clickPoint = Point2D(FXGL.getInput().mouseXWorld, FXGL.getInput().mouseYWorld)
        //获取向量值
        val vector = clickPoint.subtract(entity.center).normalize()
        // 将entity转向向量的方向
        //var degrees = Math.toDegrees(Math.atan2(vector.y, vector.x))
        // println("degrees->" +degrees)
        barrelEntity?.rotateToVector(vector)
        //println("entity->" + entity.x + "," + entity.y + ",entity->" + entity.center + "  rotation:" + entity.rotation)
        if (isLongShoot.isNotEmpty()) {
            // 生成射击大子弹
            shoot(true, vector)
        } else {
            // 生成射击子弹
            shoot(false, vector)
        }
    }

    override fun onUpdate(tpf: Double) {
        this.tpf = tpf
        updateJumping()
    }

}